//
//	File Name   :	OpenGLVertexFormat.cpp
//	Description :	OpenGLVertexFormat implementation file.
//	Author		:	William m_cVicar
//  Mail		:	william.m_cvicar@stickmenstudios.co.nz
//

//  Precompiled Header
#include "CommonDefines.h"
#ifdef OPENGL

//  Library Includes

//  Local Includes
#include "VertexFormatBase.h"
#include <gl\GL.h>
#include "OpenGLExtensions.h"

//  This includes
#include "OpenGLVertexFormat.h"

//	Macros

//  Static Variables

//  Static Function Prototypes

//  Implementation

namespace Protein
{

VertexFormat::VertexFormat( const VertexFormatBase* _pFormat )
: m_uiStride		( _pFormat->Stride() )
, m_hasPosition		( 0 )	
, m_positionChannels( 0 )
, m_positionType	( 0 )
, m_positionOffset	( 0 )
, m_hasNormal		( 0 )
, m_normalChannels	( 0 )
, m_normalType		( 0 )
, m_normalOffset	( 0 )
, m_hasTCoord		( 0 )
, m_tCoordChannels	( 0 )
, m_tCoordType		( 0 )
, m_tCoordOffset	( 0 )
, m_hasColor		( 0 )
, m_colorChannels	( 0 )
, m_colorType		( 0 )
, m_colorOffset		( 0 )
{
	for( u32 i = 0; i < _pFormat->NumAttributes(); ++i )
	{
		eSemanticType eType;
		eSemanticFormat eFormat;
		u32 uiOffset;
		_pFormat->GetElement(i, uiOffset, eType, eFormat );
		switch( eType )
		{
			case ST_POSITION:
				m_hasPosition		= 1;
				m_positionType		= GL_FLOAT;		//some mapping between format and OPENGL equivalent needed
				m_positionChannels	= 3;			//3 floats per position vector
				m_positionOffset	= uiOffset;
			break;

			case ST_COLOUR:
				m_hasColor			= 1;
				m_colorType			= GL_FLOAT;
				m_colorChannels		= 4;
				m_colorOffset		= uiOffset;

			break;

			case ST_NORMAL:
				m_hasNormal			= 1;
				m_normalChannels	= 3;
				m_normalType		= GL_FLOAT;
				m_normalOffset		= uiOffset;
			break;

			case ST_TEXCOORD:
				m_hasTCoord			= 1;
				m_tCoordChannels	= 2;
				m_tCoordType		= GL_FLOAT;
				m_tCoordOffset		= uiOffset;
			break;
		}
	}
}

VertexFormat::~VertexFormat()
{

}

void VertexFormat::Enable()
{
	if( m_hasPosition > 0 )
    {
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(m_positionChannels, m_positionType, m_uiStride, BUFFER_OFFSET( m_positionOffset ) );
    }

    if( m_hasNormal > 0 )
    {
        glEnableClientState(GL_NORMAL_ARRAY);
        glNormalPointer(m_normalType, m_uiStride, BUFFER_OFFSET( m_normalOffset ) );
    }

    if( m_hasTCoord > 0 )
    {
        OpenGLExtensions::glClientActiveTexture(GL_TEXTURE0);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
        glTexCoordPointer(m_tCoordChannels, m_tCoordType, m_uiStride, BUFFER_OFFSET( m_tCoordOffset ) );
    }

    if( m_hasColor > 0 )
    {
        glEnableClientState(GL_COLOR_ARRAY);
        glColorPointer(m_colorChannels, m_colorType, m_uiStride, BUFFER_OFFSET( m_colorOffset ) );
    }
}

void VertexFormat::Disable()
{
	if( m_hasPosition > 0 )
		glDisableClientState( GL_VERTEX_ARRAY );

	if( m_hasNormal > 0 )
		glDisableClientState( GL_NORMAL_ARRAY );

    if( m_hasTCoord > 0 )
    {
        OpenGLExtensions::glClientActiveTexture(GL_TEXTURE0);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    }

    if( m_hasColor>0 )
        glDisableClientState(GL_COLOR_ARRAY);
}

}

#endif